home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1995 #1 / Amiga Plus 1995 #1.iso / testprogramme / diskspeed / src / diskspeed.c < prev    next >
C/C++ Source or Header  |  1994-12-13  |  62KB  |  2,428 lines

  1. /*
  2.  *                          DiskSpeed v4.2
  3.  *                          ScsiSpeed v4.2
  4.  *                                by
  5.  *                           Michael Sinz
  6.  *
  7.  *            Copyright (c) 1989-1992 by MKSoft Development
  8.  *
  9.  *            MKSoft Development
  10.  *            163 Appledore Drive
  11.  *            Downingtown, PA 19335
  12.  *
  13.  * Yes, this is yet another disk speed testing program, but with a few
  14.  * differences.  It was designed to give the most accurate results of the
  15.  * true disk performance in the system.  For this reason many of
  16.  * DiskSpeed's results may look either lower or higher than current disk
  17.  * performance tests.
  18.  *
  19.  ******************************************************************************
  20.  *                                          *
  21.  *    Reading legal mush can turn your brain into guacamole!              *
  22.  *                                          *
  23.  *        So here is some of that legal mush:                  *
  24.  *                                          *
  25.  * Permission is hereby granted to distribute this program's source          *
  26.  * executable, and documentation for non-commercial purposes, so long as the  *
  27.  * copyright notices are not removed from the sources, executable or          *
  28.  * documentation.  This program may not be distributed for a profit without   *
  29.  * the express written consent of the author Michael Sinz.              *
  30.  *                                          *
  31.  * This program is not in the public domain.                      *
  32.  *                                          *
  33.  * Fred Fish is expressly granted permission to distribute this program's     *
  34.  * source and executable as part of the "Fred Fish freely redistributable     *
  35.  * Amiga software library."                              *
  36.  *                                          *
  37.  * Permission is expressly granted for this program and it's source to be     *
  38.  * distributed as part of the Amicus Amiga software disks, and the          *
  39.  * First Amiga User Group's Hot Mix disks.                      *
  40.  *                                          *
  41.  ******************************************************************************
  42.  *
  43.  * Main code and testing sections...
  44.  */
  45.  
  46. #include    <exec/types.h>
  47. #include    <exec/execbase.h>
  48. #include    <exec/memory.h>
  49. #include    <exec/lists.h>
  50. #include    <exec/nodes.h>
  51. #include    <exec/devices.h>
  52. #include    <exec/io.h>
  53. #include    <exec/ports.h>
  54. #include    <devices/timer.h>
  55. #include    <dos/dos.h>
  56. #include    <dos/dosextens.h>
  57. #include    <devices/trackdisk.h>
  58. #include    <intuition/intuition.h>
  59. #include    <intuition/screens.h>
  60. #include    <workbench/workbench.h>
  61. #include    <workbench/startup.h>
  62.  
  63. #include    <clib/exec_protos.h>
  64. #include    <clib/dos_protos.h>
  65. #include    <clib/timer_protos.h>
  66. #include    <clib/intuition_protos.h>
  67. #include    <clib/icon_protos.h>
  68.  
  69. #include    <pragmas/exec_pragmas.h>
  70. #include    <pragmas/dos_pragmas.h>
  71. #include    <pragmas/timer_pragmas.h>
  72. #include    <pragmas/intuition_pragmas.h>
  73. #include    <pragmas/icon_pragmas.h>
  74.  
  75. #include    <string.h>
  76. #include    <stdio.h>
  77.  
  78. #include    "renderinfo.h"
  79. #include    "mks_list.h"
  80. #include    "makeboxes.h"
  81.  
  82. #ifdef    SCSI_SPEED
  83.  
  84. #include    "scsispeed_rev.h"
  85.  
  86. #else    /* SCSI_SPEED */
  87.  
  88. #include    "diskspeed_rev.h"
  89.  
  90. #endif    /* SCSI_SPEED */
  91.  
  92. /*
  93.  * First, the timer stuff...
  94.  */
  95. struct MyTimer
  96. {
  97. struct    timerequest    *tr;
  98. struct    timeval        time;
  99. struct    MsgPort        *port;
  100.     BOOL        Open;
  101. };
  102.  
  103. /*
  104.  * The "TextLine" structure used to display text in the information
  105.  * "window" in DiskSpeed.
  106.  */
  107. struct    TextLine
  108. {
  109. struct    Node    tl_Node;
  110.     ULONG    tl_Size;    /* Size of the allocation */
  111.     char    tl_Text[1];    /* For the NULL... */
  112. };
  113.  
  114. /*
  115.  * My global structure...
  116.  */
  117. struct DiskSpeed
  118. {
  119. struct    Window        *Window;    /* The DiskSpeed window... */
  120. struct    RenderInfo    *ri;        /* MKSoft Render Info */
  121.  
  122. #ifdef    SCSI_SPEED
  123.  
  124. struct    IOExtTD        DiskIO;        /* Disk IO request */
  125.  
  126. #endif    /* SCSI_SPEED */
  127.  
  128.     BPTR    Output;        /* The output file handle! */
  129. struct    Process    *Me;        /* Pointer to my process... */
  130. struct    MyTimer    *timer;        /* Pointer to a timer structure */
  131.  
  132. #ifndef    SCSI_SPEED
  133.  
  134. struct    FileInfoBlock    *fib;    /* Pointer to a FileInfoBlock */
  135.  
  136. #endif    /* !SCSI_SPEED */
  137.  
  138. /* */
  139. struct    MinList    TextList;    /* The list the results test is linked to... */
  140. struct    DisplayList    *List;    /* The "List" gadget */
  141. /* */
  142.     ULONG    Min_Time;    /* Minimum time in seconds for a test */
  143.     ULONG    Base_CPU;    /* Base CPU available... */
  144.     ULONG    CPU_Total;    /* Sum of CPU availability */
  145.     ULONG    CPU_Count;    /* Count of CPU availability */
  146.  
  147. /* Testing parameters */
  148.     UBYTE    HighDMA;    /* Set to TRUE for high video DMA... */
  149.     UBYTE    Test_DIR;    /* Set to test directory stuff */
  150.     UBYTE    Test_SEEK;    /* Set to test SEEK/READ */
  151.     UBYTE    pad;
  152.  
  153.     ULONG    Align_Types;    /* Set bits of alignment types... */
  154.     ULONG    Mem_TYPES;    /* Set memory type flags to test... */
  155.     ULONG    Test_Size[4];    /* The four test sizes... */
  156.  
  157. /* Now for the gadgets */
  158. struct    Gadget    DeviceGadget;
  159. struct    Gadget    CommentsGadget;
  160. struct    Gadget    StartTestGadget;
  161. struct    Gadget    SaveResultsGadget;
  162. struct    Gadget    StopTestGadget;
  163.  
  164. struct    StringInfo    DeviceInfo;
  165. struct    StringInfo    CommentsInfo;
  166.  
  167. struct    Border    StringBorder[4];
  168. struct    Border    ActionBorder[4];
  169. struct    Border    DetailBorder[2];
  170.  
  171. struct    IntuiText    DeviceText;
  172. struct    IntuiText    CommentsText;
  173. struct    IntuiText    StartTest;
  174. struct    IntuiText    SaveResults;
  175. struct    IntuiText    StopTest;
  176.  
  177.     SHORT    StringVectors[5*2*4];
  178.     SHORT    ActionVectors[5*2*2];
  179.  
  180. /* */
  181.     char    Device[256];    /* Device name under test... */
  182.     char    Comments[256];    /* Comments string gadget... */
  183.     char    Undo[256];    /* Our one UNDO buffer... */
  184.  
  185. /* */
  186.     char    CPU_Type[6];    /* 680?0 in this string (plus NULL) */
  187.     char    Exec_Ver[14];    /* Version of Exec */
  188.  
  189. /* */
  190.     char    tmp1[256];    /* Some temp buffer space... */
  191. };
  192.  
  193. #define    DEVICE_GADGET    1
  194. #define    COMMENT_GADGET    2
  195. #define    TEST_GADGET    3
  196. #define    SAVE_GADGET    4
  197. #define    STOP_GADGET    5
  198.  
  199. extern    struct    Library    *SysBase;
  200. extern    struct    Library    *DOSBase;
  201. extern    struct    Library    *IntuitionBase;
  202. extern    struct    Library    *GfxBase;
  203. extern    struct    Library    *IconBase;
  204.     struct    Library    *LayersBase;
  205.  
  206. /* Some prototypes not given... BTW - This is mainly needed for 1.3 compatibility... ARG!!! */
  207. void *CreateExtIO( struct MsgPort *msg, long size );
  208. struct MsgPort *CreatePort( UBYTE *name, long pri );
  209. void DeleteExtIO( struct IORequest *io );
  210. void DeletePort( struct MsgPort *io );
  211. void DeleteTask( struct Task *task );
  212. void NewList( struct List *list );
  213.  
  214. #ifdef    SCSI_SPEED
  215.  
  216. char    BYTES_READ[]=    "Read from SCSI:";
  217. char    COPYRIGHT[]=    "MKSoft ScsiSpeed 4.2  Copyright © 1989-92 MKSoft Development" VERSTAG;
  218. char    RESULTS_FILE[]=    "ScsiSpeed.Results";
  219.  
  220. #else    /* SCSI_SPEED */
  221.  
  222. char    FILE_CREATE[]=    "File Create:   ";
  223. char    FILE_OPEN[]=    "File Open:     ";
  224. char    FILE_SCAN[]=    "Directory Scan:";
  225. char    FILE_DELETE[]=    "File Delete:   ";
  226. char    SEEK_READ[]=    "Seek/Read:     ";
  227.  
  228. char    BYTES_CREATE[]=    "Create file:   ";
  229. char    BYTES_WRITE[]=    "Write to file: ";
  230. char    BYTES_READ[]=    "Read from file:";
  231.  
  232. char    SEEK_UNITS[]=    "seeks/sec";
  233. char    FILE_UNITS[]=    "files/sec";
  234.  
  235. char    FILE_STRING[]=    "%04lx DiskSpeed Test File ";
  236.  
  237. char    TEST_DIR[]=    " DiskSpeed Test Directory ";
  238.  
  239. char    COPYRIGHT[]=    "MKSoft DiskSpeed 4.2  Copyright © 1989-92 MKSoft Development" VERSTAG;
  240. char    RESULTS_FILE[]=    "DiskSpeed.Results";
  241.  
  242. #endif    /* SCSI_SPEED */
  243.  
  244. char    BYTE_UNITS[]=    "bytes/sec";
  245.  
  246. char    START_TEST[]=    "Start Test";
  247. char    SAVE_RESULTS[]=    "Save Results";
  248. char    STOP_TEST[]=    "Stop Test";
  249.  
  250. static char fontnam[11]="topaz.font";
  251. struct TextAttr TOPAZ80={fontnam,8,0,FPF_ROMFONT};
  252.  
  253. /*
  254.  * This is the minimum time for test that can be extended/shorted automatically
  255.  * This number should not be set too low otherwise the test results will be
  256.  * inaccurate due to timer granularity.  (in seconds)
  257.  */
  258. #ifdef    SCSI_SPEED
  259.  
  260. #define    MIN_TEST_TIME    20
  261.  
  262. #else    /* SCSI_SPEED */
  263.  
  264. #define    MIN_TEST_TIME    8
  265. #define    NUM_FILES    200
  266.  
  267. #endif    /* SCSI_SPEED */
  268.  
  269. /*
  270.  * This section of code is used to test CPU availability.  Due to the nature of
  271.  * the code, the actual test code for the task is in assembly...
  272.  */
  273. extern    ULONG    __far    CPU_Use_Base;
  274. extern    ULONG    __far    CPU_State_Flag;
  275. extern    ULONG    __far    CPU_Count_Low;
  276. extern    ULONG    __far    CPU_Count_High;
  277.  
  278. struct Task *Init_CPU_Available(void);
  279. void Free_CPU_Available(void);
  280. void CPU_Calibrate(void);
  281.  
  282.  
  283. /* The Wait pointer I use... */
  284. USHORT __chip WaitPointer[36] =
  285. {
  286.     0x0000, 0x0000, 0x0400, 0x07C0, 0x0000, 0x07C0, 0x0100, 0x0380, 0x0000,
  287.     0x07E0, 0x07C0, 0x1FF8, 0x1FF0, 0x3FEC, 0x3FF8, 0x7FDE, 0x3FF8, 0x7FBE,
  288.     0x7FFC, 0xFF7F, 0x7EFC, 0xFFFF, 0x7FFC, 0xFFFF, 0x3FF8, 0x7FFE, 0x3FF8,
  289.     0x7FFE, 0x1FF0, 0x3FFC, 0x07C0, 0x1FF8, 0x0000, 0x07E0, 0x0000, 0x0000
  290. };
  291.  
  292. /*
  293.  * These two defines set up and clear the WaitPointer...
  294.  */
  295. #define    SetWait(x)    SetPointer(x,WaitPointer,16L,16L,-6L,0L)
  296. #define    ClearWait(x)    ClearPointer(x)
  297.  
  298. /*
  299.  * This routine returns the amount of time in the timer...
  300.  * The number returned is in Seconds...
  301.  */
  302. ULONG Read_Timer(struct MyTimer *mt)
  303. {
  304. struct    Library    *TimerBase=(struct Library *)(mt->tr->tr_node.io_Device);
  305.  
  306.     /* Get the current time... */
  307.     mt->tr->tr_node.io_Command=TR_GETSYSTIME;
  308.     mt->tr->tr_node.io_Flags=IOF_QUICK;
  309.     DoIO((struct IORequest *)(mt->tr));
  310.  
  311.     /* Subtract last timer result and store as the timer result */
  312.     SubTime(&(mt->tr->tr_time),&(mt->time));
  313.     return(mt->tr->tr_time.tv_secs);
  314. }
  315.  
  316. /*
  317.  * Start the timer...
  318.  */
  319. void Start_Timer(struct MyTimer *mt)
  320. {
  321.     /* Get the current time... */
  322.     mt->tr->tr_node.io_Command=TR_GETSYSTIME;
  323.     mt->tr->tr_node.io_Flags=IOF_QUICK;
  324.     DoIO((struct IORequest *)(mt->tr));
  325.  
  326.     /* Store current time as the timer result */
  327.     mt->time=mt->tr->tr_time;
  328.  
  329.     /*
  330.      * This here is a nasty trick...  Since the timer device
  331.      * has a low resolution, we wait until we get to the exact
  332.      * cross-over from one TICK to the next.  We know that the
  333.      * tick value is larger than 10 so if the difference
  334.      * between two calls to the timer is > 10 then it must
  335.      * have been a TICK that just went through.  This is
  336.      * not "friendly" code but since we are testing the system
  337.      * and it is not "application" code, it is not a problem.
  338.      */
  339.     while ((mt->tr->tr_time.tv_micro-mt->time.tv_micro) < 10)
  340.     {
  341.         /* Store current time as the timer result */
  342.         mt->time=mt->tr->tr_time;
  343.  
  344.         /* Get the current time... */
  345.         mt->tr->tr_node.io_Command=TR_GETSYSTIME;
  346.         mt->tr->tr_node.io_Flags=IOF_QUICK;
  347.         DoIO((struct IORequest *)(mt->tr));
  348.     }
  349.  
  350.     /* Store current time as the timer result */
  351.     mt->time=mt->tr->tr_time;
  352. }
  353.  
  354. /*
  355.  * Stop the timer...
  356.  */
  357. void Stop_Timer(struct MyTimer *mt)
  358. {
  359. struct    Library    *TimerBase=(struct Library *)(mt->tr->tr_node.io_Device);
  360.  
  361.     /* Get the current time... */
  362.     mt->tr->tr_node.io_Command=TR_GETSYSTIME;
  363.     mt->tr->tr_node.io_Flags=IOF_QUICK;
  364.     DoIO((struct IORequest *)(mt->tr));
  365.  
  366.     /* Subtract last timer result and store as the timer result */
  367.     SubTime(&(mt->tr->tr_time),&(mt->time));
  368.     mt->time=mt->tr->tr_time;
  369. }
  370.  
  371. /*
  372.  * Free a MyTimer structure as best as possible.  Do all of the error checks
  373.  * here since this will also be called for partial timer initializations.
  374.  */
  375. void Free_Timer(struct MyTimer *mt)
  376. {
  377.     if (mt)
  378.     {
  379.         if (mt->port)
  380.         {
  381.             if (mt->tr)
  382.             {
  383.                 if (mt->Open)
  384.                 {
  385.                     CloseDevice((struct IORequest *)(mt->tr));
  386.                 }
  387.                 DeleteExtIO((struct IORequest *)(mt->tr));
  388.             }
  389.             DeletePort(mt->port);
  390.         }
  391.         FreeMem(mt,sizeof(struct MyTimer));
  392.     }
  393. }
  394.  
  395. /*
  396.  * Initialize a MyTimer structure.  It will return NULL if it did not work.
  397.  */
  398. struct MyTimer *Init_Timer(void)
  399. {
  400. struct    MyTimer    *mt;
  401.  
  402.     if (mt=AllocMem(sizeof(struct MyTimer),MEMF_PUBLIC|MEMF_CLEAR))
  403.     {
  404.         mt->Open=FALSE;
  405.         if (mt->port=CreatePort(NULL,0L))
  406.         {
  407.             if (mt->tr=CreateExtIO(mt->port,sizeof(struct timerequest)))
  408.             {
  409.                 if (!OpenDevice(TIMERNAME,UNIT_VBLANK,(struct IORequest *)(mt->tr),0L))
  410.                 {
  411.                     mt->Open=TRUE;
  412.                 }
  413.             }
  414.         }
  415.         if (!(mt->Open))
  416.         {
  417.             Free_Timer(mt);
  418.             mt=NULL;
  419.         }
  420.     }
  421.     return(mt);
  422. }
  423.  
  424. /*
  425.  * Now, for the routines that will pull in the lines and display them as
  426.  * needed in the display...
  427.  */
  428. void AddDisplayLine(struct DiskSpeed *global,char *line)
  429. {
  430.     ULONG        size=strlen(line);
  431. struct    TextLine    *tline;
  432.  
  433.     if (global->Window)
  434.     {
  435.         if (tline=AllocMem(size+=sizeof(struct TextLine),MEMF_PUBLIC|MEMF_CLEAR))
  436.         {
  437.             tline->tl_Size=size;
  438.             tline->tl_Node.ln_Name=tline->tl_Text;
  439.             strcpy(tline->tl_Text,line);
  440.  
  441.             AddTail((struct List *)&(global->TextList),&(tline->tl_Node));
  442.  
  443.             /* Now display it... */
  444.             FreshList(global->Window,global->List,&(global->TextList));
  445.         }
  446.     }
  447.     else if (global->Output)
  448.     {
  449.         Write(global->Output,line,size);
  450.         Write(global->Output,"\n",1);
  451.     }
  452. }
  453.  
  454. void FreeDisplayList(struct DiskSpeed *global)
  455. {
  456. struct    TextLine    *tline;
  457.  
  458.     while (tline=(struct TextLine *)RemHead((struct List *)&(global->TextList)))
  459.     {
  460.         FreeMem(tline,tline->tl_Size);
  461.     }
  462.  
  463.     /* Update the display */
  464.     if (global->Window) FreshList(global->Window,global->List,NULL);
  465. }
  466.  
  467. /*...*/
  468.  
  469. BOOL Check_Quit(struct DiskSpeed *global)
  470. {
  471. BOOL    worked=TRUE;
  472. struct    IntuiMessage    *msg;
  473.  
  474.     if (global->Window)
  475.     {
  476.         while (msg=(struct IntuiMessage *)GetMsg(global->Window->UserPort))
  477.         {
  478.             if (msg->Class==CLOSEWINDOW) worked=FALSE;
  479.             else if (msg->Class==GADGETUP) if (msg->IAddress==&(global->StopTestGadget)) worked=FALSE;
  480.             Check_ListGadget(global->Window,msg);
  481.             ReplyMsg((struct Message *)msg);
  482.         }
  483.     }
  484.  
  485.     if (SetSignal(0,SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) worked=FALSE;
  486.  
  487.     if (!worked) AddDisplayLine(global,"*** Interrupted by user ***");
  488.  
  489.     return(worked);
  490. }
  491.  
  492. /*...*/
  493.  
  494. /*
  495.  * It knows that the Y value is fixed point by n-digits...
  496.  */
  497. ULONG MaxDivide(ULONG x,ULONG y,ULONG digits)
  498. {
  499. ULONG    result;
  500. ULONG    num=0;    /* Number of 10 units adjusted for so far */
  501.  
  502.     while ((x<399999999) && (num<digits))
  503.     {
  504.         x*=10;
  505.         num++;
  506.     }
  507.  
  508.     while (num<digits)
  509.     {
  510.         num++;
  511.         if (num==digits) y+=5;    /* Round it if last digit... */
  512.         y=y/10;
  513.     }
  514.  
  515.     if (y) result=x/y;
  516.     else result=-1;    /* MAX INT if y=0 */
  517.  
  518.     return(result);
  519. }
  520.  
  521. /*
  522.  * Build a string and add it to the display of results.
  523.  * This routine knows how to take the timer results and the CPU
  524.  * results and format them into a string with the given header
  525.  * and the given unit of measure.
  526.  */
  527. VOID Display_Result(struct DiskSpeed *global,char *Header,ULONG number,char *Units)
  528. {
  529. char    *p=global->tmp1;
  530. char    format[48];
  531. ULONG    clicks;    /* To figure out the number of clicks/second */
  532. ULONG    time;
  533. ULONG    tmp_time;
  534.  
  535.     /* First, make sure (as best as possible) that the CPU values are right */
  536.     CPU_State_Flag=TRUE;
  537.     Delay(1);    /* Let it run into the TRUE CPU_State_Flag */
  538.  
  539.     /* 1,000,000 micro = 1 second... */
  540.     time=(global->timer->time.tv_secs * 1000000) + global->timer->time.tv_micro;
  541.     /* time is now in micro seconds... */
  542.  
  543.     number=MaxDivide(number,time,6);
  544.  
  545.     strcpy(format,"%s %9ld %s");
  546.     if (!number)
  547.     {
  548.         strcpy(format,"%s       < %ld %s");
  549.         number=1;
  550.     }
  551.  
  552.     if (global->Base_CPU)
  553.     {
  554.         tmp_time=time;    /* For below... */
  555.  
  556.         while (CPU_Count_High)
  557.         {
  558.             /* Adjust the time and the CPU count as needed */
  559.             tmp_time=tmp_time >> 1;
  560.             CPU_Count_Low=CPU_Count_Low >> 1;
  561.             if (CPU_Count_High & 1) CPU_Count_Low += 0x80000000;
  562.             CPU_Count_High=CPU_Count_High >> 1;
  563.         }
  564.  
  565.         clicks=MaxDivide(CPU_Count_Low,tmp_time,6);
  566.         clicks=(MaxDivide(clicks,global->Base_CPU,3)+5)/10;
  567.         global->CPU_Total+=clicks;
  568.         global->CPU_Count++;
  569.  
  570.         strcat(format,"  |  CPU Available: %ld%%");
  571.     }
  572.  
  573.     sprintf(p,format,Header,number,Units,clicks);
  574.  
  575.     AddDisplayLine(global,p);
  576. }
  577.  
  578. VOID Display_Error(struct DiskSpeed *global,char *test)
  579. {
  580.     sprintf(global->tmp1,"Error:  %s test failed.",test);
  581.     AddDisplayLine(global,global->tmp1);
  582. }
  583.  
  584. #ifdef    SCSI_SPEED
  585.  
  586. BOOL SpeedTest(struct DiskSpeed *global,ULONG size,ULONG offset,ULONG mem_type)
  587. {
  588. BOOL    worked=TRUE;
  589. char    *buffer;
  590. char    *mem;        /* What we really allocated */
  591. char    *type;
  592. char    *type2;
  593. ULONG    count;
  594.  
  595.     AddDisplayLine(global,"");
  596.  
  597.     type="FAST";
  598.     if (mem_type & MEMF_CHIP) type="CHIP";
  599.  
  600.     type2="LONG";
  601.     if (offset & 2) type2="WORD";
  602.     if (offset & 1) type2="BYTE";
  603.  
  604.     /* Round to block sizes */
  605.     size=(size+511) & (~511);
  606.  
  607.     if (mem=AllocMem(size+offset,mem_type|MEMF_PUBLIC))
  608.     {
  609.         /* Set up memory... */
  610.         buffer=&(mem[offset]);
  611.  
  612.         sprintf(global->tmp1,"Testing with a %ld byte, MEMF_%s, %s-aligned buffer.",size,type,type2);
  613.         AddDisplayLine(global,global->tmp1);
  614.  
  615.         count=0;
  616.  
  617.         Start_Timer(global->timer);
  618.         Init_CPU_Available();        /* Start counting free CPU cycles... */
  619.         while ((worked &= Check_Quit(global)) && (Read_Timer(global->timer) < global->Min_Time))
  620.         {
  621.             global->DiskIO.iotd_Req.io_Command=CMD_READ;
  622.             global->DiskIO.iotd_Req.io_Flags=NULL;
  623.             global->DiskIO.iotd_Req.io_Length=size;
  624.             global->DiskIO.iotd_Req.io_Data=buffer;
  625.             global->DiskIO.iotd_Req.io_Offset=count;
  626.  
  627.             DoIO(&(global->DiskIO));
  628.             count+=global->DiskIO.iotd_Req.io_Actual;
  629.  
  630.             if (global->DiskIO.iotd_Req.io_Error)
  631.             {
  632.                 worked=FALSE;
  633.                 Display_Error(global,"Device Reported Error on Read");
  634.             }
  635.         }
  636.         Stop_Timer(global->timer);
  637.  
  638.         if (worked) Display_Result(global,BYTES_READ,count,BYTE_UNITS);
  639.  
  640.         Free_CPU_Available();
  641.         FreeMem(mem,size+offset);
  642.     }
  643.     else
  644.     {
  645.         sprintf(global->tmp1,"Skipping %ld byte MEMF_%s test due to lack of memory.",size,type);
  646.         AddDisplayLine(global,global->tmp1);
  647.     }
  648.  
  649.     return(worked);
  650. }
  651.  
  652. #else    /* SCSI_SPEED */
  653.  
  654. /*
  655.  * In order to keep the file create test fair, it must always do
  656.  * the same number of files.  The way filing systems work, many times
  657.  * the get slower as the number of files in a directory grow
  658.  */
  659. BOOL CreateFileTest(struct DiskSpeed *global)
  660. {
  661. BPTR    file;
  662. ULONG    count;
  663. BOOL    worked=TRUE;
  664. char    *p=global->tmp1;    /* For speed reasons */
  665.  
  666.     Start_Timer(global->timer);
  667.     Init_CPU_Available();        /* Start counting free CPU cycles... */
  668.  
  669.     for (count=0;(count<NUM_FILES) && (worked &= Check_Quit(global));count++)
  670.     {
  671.         sprintf(p,FILE_STRING,count);
  672.         if (file=Open(p,MODE_NEWFILE)) Close(file);
  673.         else
  674.         {
  675.             Display_Error(global,"File Create");
  676.             worked=FALSE;
  677.         }
  678.     }
  679.  
  680.     Stop_Timer(global->timer);
  681.  
  682.     if (worked) Display_Result(global,FILE_CREATE,NUM_FILES,FILE_UNITS);
  683.  
  684.     Free_CPU_Available();
  685.  
  686.     return(worked);
  687. }
  688.  
  689. BOOL OpenFileTest(struct DiskSpeed *global)
  690. {
  691. BPTR    file;
  692. ULONG    count=0;
  693. BOOL    worked=TRUE;
  694. char    *p=global->tmp1;
  695.  
  696.     Start_Timer(global->timer);
  697.     Init_CPU_Available();        /* Start counting free CPU cycles... */
  698.     while ((worked &= Check_Quit(global)) && (Read_Timer(global->timer) < global->Min_Time))
  699.     {
  700.         sprintf(p,FILE_STRING,(ULONG)(count % NUM_FILES));
  701.         count++;
  702.         if (file=Open(p,MODE_OLDFILE)) Close(file);
  703.         else
  704.         {
  705.             Display_Error(global,"File Open");
  706.             worked=FALSE;
  707.         }
  708.     }
  709.     Stop_Timer(global->timer);
  710.  
  711.     if (worked) Display_Result(global,FILE_OPEN,count,FILE_UNITS);
  712.  
  713.     Free_CPU_Available();
  714.     return(worked);
  715. }
  716.  
  717. BOOL ScanDirectoryTest(struct DiskSpeed *global)
  718. {
  719. BPTR    lock=NULL;
  720. ULONG    count=0;
  721. BOOL    worked=TRUE;
  722.  
  723.     Start_Timer(global->timer);
  724.     Init_CPU_Available();        /* Start counting free CPU cycles... */
  725.     while ((worked &= Check_Quit(global)) && (Read_Timer(global->timer) < global->Min_Time))
  726.     {
  727.         if (lock)
  728.         {
  729.             if (!ExNext(lock,global->fib)) lock=NULL;
  730.             else count++;
  731.         }
  732.         else
  733.         {
  734.             CurrentDir(lock=CurrentDir(NULL));
  735.             if (Examine(lock,global->fib)) count++;
  736.             else
  737.             {
  738.                 Display_Error(global,"Directory Scan");
  739.                 worked=FALSE;
  740.             }
  741.         }
  742.     }
  743.     Stop_Timer(global->timer);
  744.  
  745.     if (worked) Display_Result(global,FILE_SCAN,count,FILE_UNITS);
  746.  
  747.     Free_CPU_Available();
  748.     return(worked);
  749. }
  750.  
  751. /*
  752.  * In order to keep the file delete test fair, it must always do
  753.  * the same number of files.  The way filing systems work, many times
  754.  * the get slower as the number of files in a directory grow
  755.  */
  756. BOOL DeleteFileTest(struct DiskSpeed *global)
  757. {
  758. ULONG    count;
  759. BOOL    worked=TRUE;
  760. char    *p=global->tmp1;
  761.  
  762.     Start_Timer(global->timer);
  763.     Init_CPU_Available();        /* Start counting free CPU cycles... */
  764.  
  765.     for (count=0;(count<NUM_FILES) && (worked &= Check_Quit(global));count++)
  766.     {
  767.         sprintf(p,FILE_STRING,count);
  768.         if (!DeleteFile(p))
  769.         {
  770.             Display_Error(global,"File Delete");
  771.             worked=FALSE;
  772.         }
  773.     }
  774.  
  775.     Stop_Timer(global->timer);
  776.  
  777.     if (worked) Display_Result(global,FILE_DELETE,NUM_FILES,FILE_UNITS);
  778.  
  779.     Free_CPU_Available();
  780.  
  781.     return(worked);
  782. }
  783.  
  784. BOOL SeekReadTest(struct DiskSpeed *global)
  785. {
  786. BPTR    file;
  787. ULONG    size;
  788. ULONG    count;
  789. LONG    pos=0;
  790. LONG    buffer[16];
  791. BOOL    worked=FALSE;
  792. void    *buf;
  793.  
  794.     /* First we build a file by writing the ROM to disk... */
  795.     if (file=Open(FILE_STRING,MODE_NEWFILE))
  796.     {
  797.         size=0x40000;    /* Start by asking for 256K */
  798.         while (size && (!(buf=AllocMem(size,MEMF_PUBLIC)))) size=size>>1;
  799.  
  800.         if (buf)
  801.         {
  802.             worked=TRUE;
  803.             /* Write a 256K file... */
  804.             count=0x40000/size;
  805.             while ((count>0) && (worked&=Check_Quit(global)))
  806.             {
  807.                 count--;
  808.                 if (size!=Write(file,buf,size))
  809.                 {
  810.                     worked=FALSE;
  811.                     Display_Error(global,"Seek/Read");
  812.                 }
  813.             }
  814.             FreeMem(buf,size);
  815.         }
  816.         else Display_Error(global,"Seek/Read");
  817.  
  818.         Start_Timer(global->timer);
  819.         Init_CPU_Available();        /* Start counting free CPU cycles... */
  820.         while ((worked &= Check_Quit(global)) && (Read_Timer(global->timer) < global->Min_Time))
  821.         {
  822.             Seek(file,pos,OFFSET_BEGINING);
  823.             Read(file,buffer,64);
  824.             count++;
  825.  
  826.             Seek(file,-(pos+64),OFFSET_END);
  827.             Read(file,buffer,64);
  828.             count++;
  829.  
  830.             Seek(file,-(pos+(size/3)),OFFSET_CURRENT);
  831.             Read(file,buffer,64);
  832.             count++;
  833.  
  834.             /* Come up with another position... */
  835.             pos=(pos+(size/11)) % (size/3);
  836.         }
  837.         Stop_Timer(global->timer);
  838.  
  839.         if (worked) Display_Result(global,SEEK_READ,count,SEEK_UNITS);
  840.  
  841.         Free_CPU_Available();
  842.  
  843.         Close(file);
  844.         DeleteFile(FILE_STRING);
  845.     }
  846.     else Display_Error(global,"Seek/Read");
  847.  
  848.     return(worked);
  849. }
  850.  
  851. BOOL SpeedTest(struct DiskSpeed *global,ULONG size,ULONG offset,ULONG mem_type)
  852. {
  853. BOOL    worked=TRUE;
  854. char    *buffer;
  855. char    *mem;        /* What we really allocated */
  856. char    *type;
  857. char    *type2;
  858. ULONG    loop;
  859. ULONG    count;
  860. LONG    times;
  861. BPTR    file=NULL;
  862.  
  863.     AddDisplayLine(global,"");
  864.  
  865.     type="FAST";
  866.     if (mem_type & MEMF_CHIP) type="CHIP";
  867.  
  868.     type2="LONG";
  869.     if (offset & 2) type2="WORD";
  870.     if (offset & 1) type2="BYTE";
  871.  
  872.     if (mem=AllocMem(size+offset,mem_type|MEMF_PUBLIC))
  873.     {
  874.         /* Set up memory... */
  875.         buffer=&(mem[offset]);
  876.  
  877.         for (loop=0;loop<size;loop++) buffer[loop]=(UBYTE)loop;
  878.  
  879.         sprintf(global->tmp1,"Testing with a %ld byte, MEMF_%s, %s-aligned buffer.",size,type,type2);
  880.         AddDisplayLine(global,global->tmp1);
  881.  
  882.         count=0;
  883.         times=0;
  884.  
  885.         Start_Timer(global->timer);
  886.         Init_CPU_Available();        /* Start counting free CPU cycles... */
  887.         while ((worked &= Check_Quit(global)) && (Read_Timer(global->timer) < global->Min_Time))
  888.         {
  889.             if (times<1)
  890.             {
  891.                 if (file) Close(file);
  892.                 DeleteFile(FILE_STRING);
  893.                 if (!(file=Open(FILE_STRING,MODE_NEWFILE)))
  894.                 {
  895.                     Display_Error(global,"Create File");
  896.                     worked=FALSE;
  897.                 }
  898.                 times=0x40000/size;    /* Try to make file at least 256K size */
  899.             }
  900.             if (file)
  901.             {
  902.                 if (size!=Write(file,buffer,size))
  903.                 {
  904.                     Display_Error(global,"Create File");
  905.                     worked=FALSE;
  906.                 }
  907.                 else count+=size;
  908.                 times--;
  909.             }
  910.         }
  911.         Stop_Timer(global->timer);
  912.  
  913.         if (worked) Display_Result(global,BYTES_CREATE,count,BYTE_UNITS);
  914.  
  915.         /* Fill out the file... */
  916.         if (file) while ((worked &= Check_Quit(global)) && (times>0))
  917.         {
  918.             Write(file,buffer,size);
  919.             times--;
  920.         }
  921.  
  922.         if (file) Close(file);
  923.         file=NULL;
  924.  
  925.         if (worked) if (!(file=Open(FILE_STRING,MODE_OLDFILE)))
  926.         {
  927.             Display_Error(global,"Write File");
  928.             worked=FALSE;
  929.         }
  930.  
  931.         count=0;
  932.         times=0;
  933.  
  934.         Start_Timer(global->timer);
  935.         Init_CPU_Available();        /* Start counting free CPU cycles... */
  936.         while ((worked &= Check_Quit(global)) && (Read_Timer(global->timer) < global->Min_Time))
  937.         {
  938.             if (times<1)
  939.             {
  940.                 Seek(file,0,OFFSET_BEGINNING);
  941.                 times=0x40000/size;    /* Try to make file at least 256K size */
  942.             }
  943.             if (size!=Write(file,buffer,size))
  944.             {
  945.                 Display_Error(global,"Write File");
  946.                 worked=FALSE;
  947.             }
  948.             else count+=size;
  949.             times--;
  950.         }
  951.         Stop_Timer(global->timer);
  952.  
  953.         if (worked) Display_Result(global,BYTES_WRITE,count,BYTE_UNITS);
  954.  
  955.         if (file) Close(file);
  956.         file=NULL;
  957.  
  958.         if (worked) if (!(file=Open(FILE_STRING,MODE_OLDFILE)))
  959.         {
  960.             Display_Error(global,"Read File");
  961.             worked=FALSE;
  962.         }
  963.  
  964.         count=0;
  965.         times=0;
  966.  
  967.         Start_Timer(global->timer);
  968.         Init_CPU_Available();        /* Start counting free CPU cycles... */
  969.         while ((worked &= Check_Quit(global)) && (Read_Timer(global->timer) < global->Min_Time))
  970.         {
  971.             if (times<1)
  972.             {
  973.                 Seek(file,0,OFFSET_BEGINNING);
  974.                 times=0x40000/size;    /* Try to make file at least 256K size */
  975.             }
  976.             if (size!=Read(file,buffer,size))
  977.             {
  978.                 Display_Error(global,"Read File");
  979.                 worked=FALSE;
  980.             }
  981.             else count+=size;
  982.             times--;
  983.         }
  984.         Stop_Timer(global->timer);
  985.  
  986.         if (worked)
  987.         {
  988.             for (loop=0;loop<size;loop++) worked &= (buffer[loop]==(UBYTE)loop);
  989.             if (!worked) AddDisplayLine(global,"*** Data Error ***  Buffer did not read correctly.");
  990.         }
  991.  
  992.         if (worked) Display_Result(global,BYTES_READ,count,BYTE_UNITS);
  993.  
  994.         if (file) Close(file);
  995.  
  996.         Free_CPU_Available();
  997.         FreeMem(mem,size+offset);
  998.         DeleteFile(FILE_STRING);
  999.     }
  1000.     else
  1001.     {
  1002.         sprintf(global->tmp1,"Skipping %ld byte MEMF_%s test due to lack of memory.",size,type);
  1003.         AddDisplayLine(global,global->tmp1);
  1004.     }
  1005.  
  1006.     return(worked);
  1007. }
  1008.  
  1009. /*
  1010.  * Clean up (remove) all of the files in the current directory...
  1011.  */
  1012. void CleanUpFiles(struct DiskSpeed *global)
  1013. {
  1014. BPTR    lock;
  1015.  
  1016.     CurrentDir(lock=CurrentDir(NULL));    /* Get current directory lock */
  1017.  
  1018.     while (lock)
  1019.     {
  1020.         if (Examine(lock,global->fib))
  1021.         {
  1022.             if (ExNext(lock,global->fib)) DeleteFile(global->fib->fib_FileName);
  1023.             else lock=NULL;
  1024.         }
  1025.         else lock=NULL;
  1026.     }
  1027. }
  1028.  
  1029. #endif    /* SCSI_SPEED */
  1030.  
  1031. void DoTests(struct DiskSpeed *global)
  1032. {
  1033. char    *p=global->tmp1;
  1034. BOOL    working;
  1035. ULONG    memtype;
  1036. ULONG    offset;
  1037. short    size;
  1038.  
  1039. #ifndef    SCSI_SPEED
  1040. char    *fstring;
  1041. LONG    buffers;
  1042. #endif    /* !SCSI_SPEED */
  1043.  
  1044.     /*
  1045.      * Ok, so now we are ready to run...  Display the
  1046.      * test conditions...
  1047.      */
  1048.     strcpy(p,"CPU: ");
  1049.     strcat(p,global->CPU_Type);
  1050.     strcat(p,"  AmigaOS Version: ");
  1051.     strcat(p,global->Exec_Ver);
  1052.     if (global->HighDMA) strcat(p,"  High");
  1053.     else strcat(p,"  Normal");
  1054.     strcat(p," Video DMA");
  1055.     AddDisplayLine(global,p);
  1056.  
  1057.     /*
  1058.      * Now, if we are in 2.0 OS, we can also find out the number of buffers
  1059.      * (maybe) on that device.  This is important.
  1060.      */
  1061. #ifdef    SCSI_SPEED
  1062.  
  1063.     sprintf(p,"Device: %s",global->Device);
  1064.  
  1065. #else    /* SCSI_SPEED */
  1066.  
  1067.     fstring="Device: %s    Buffers: <information unavailable>";
  1068.     if (DOSBase->lib_Version > 36L)
  1069.     {
  1070.         /*
  1071.          * Ok, so we can now try to get a reading of the buffers
  1072.          * for the place we are about to test...
  1073.          *
  1074.          * Note:  Since we are in the "CURRENTDIR" of the test disk,
  1075.          * we are using "" as the "device" to which to call AddBuffers()
  1076.          */
  1077.         if ((buffers=AddBuffers("",0)) > 0) fstring="Device:  %s    Buffers: %ld";
  1078.     }
  1079.  
  1080.     sprintf(p,fstring,global->Device,buffers);
  1081.  
  1082. #endif    /* SCSI_SPEED */
  1083.  
  1084.     AddDisplayLine(global,p);
  1085.  
  1086.     if (global->Comments[0])
  1087.     {
  1088.         strcpy(p,"Comments: ");
  1089.         strcat(p,global->Comments);
  1090.         AddDisplayLine(global,p);
  1091.     }
  1092.  
  1093.     AddDisplayLine(global,"");
  1094.  
  1095.     if (CPU_Use_Base) Delay(60);    /* Make sure filesystem has flushed... */
  1096.  
  1097.     Init_CPU_Available();
  1098.     if (CPU_Use_Base) Delay(75);    /* Get a quick reading (~1.5 seconds) */
  1099.     Free_CPU_Available();
  1100.  
  1101.     if (CPU_Use_Base)
  1102.     {
  1103.         /*
  1104.          * Now, generate a countdown value that is aprox 3 times 1.5 second...
  1105.          */
  1106.         CPU_Use_Base=(CPU_Count_Low * 3) + 1;
  1107.         CPU_Count_Low=CPU_Use_Base;
  1108.         Forbid();
  1109.         Start_Timer(global->timer);
  1110.         CPU_Calibrate();
  1111.         Stop_Timer(global->timer);
  1112.         Permit();
  1113.  
  1114.         /*
  1115.          * If it looks like we did not get a good reading,
  1116.          * set up CPU_Use_Base to 0 in order to turn off
  1117.          * CPU readings...
  1118.          */
  1119.         if (global->timer->time.tv_secs<4)
  1120.         {
  1121.             AddDisplayLine(global,"CPU Calibration shows that CPU availability tests");
  1122.             AddDisplayLine(global,"would be inaccurate in the current system state.");
  1123.             CPU_Use_Base=0;
  1124.         }
  1125.         else CPU_Use_Base=MaxDivide(CPU_Use_Base,(global->timer->time.tv_secs * 1000000) + global->timer->time.tv_micro,6);
  1126.     }
  1127.  
  1128.     global->Base_CPU=CPU_Use_Base;
  1129.  
  1130.     if (CPU_Use_Base) sprintf(p,"CPU Speed Rating: %ld",(((CPU_Use_Base/500)+1) >> 1 ));
  1131.     else strcpy(p,"No CPU Speed Rating -- CPU % not available.");
  1132.     AddDisplayLine(global,p);
  1133.     AddDisplayLine(global,"");
  1134.  
  1135.     global->CPU_Total=0L;
  1136.     global->CPU_Count=0L;
  1137.  
  1138.     working=Check_Quit(global);
  1139.  
  1140. #ifndef    SCSI_SPEED
  1141.  
  1142.     if (working) if (global->Test_DIR)
  1143.     {
  1144.         AddDisplayLine(global,"Testing directory manipulation speed.");
  1145.         if (working) working=CreateFileTest(global);
  1146.         if (working) working=OpenFileTest(global);
  1147.         if (working) working=ScanDirectoryTest(global);
  1148.         if (working) working=DeleteFileTest(global);
  1149.     }
  1150.  
  1151.     if (working) if (global->Test_SEEK)
  1152.     {
  1153.         AddDisplayLine(global,"");
  1154.         if (working) working=SeekReadTest(global);
  1155.     }
  1156.  
  1157. #endif    /* !SCSI_SPEED */
  1158.  
  1159.     /* Now for some of the more complex tests */
  1160.     /* result=SpeedTest(global,Buffer,offset,mem_type); */
  1161.  
  1162.     memtype=MEMF_FAST;
  1163.     while (memtype)
  1164.     {
  1165.         if (memtype & global->Mem_TYPES) for (offset=4;offset>0;offset=offset >> 1) if (offset & global->Align_Types)
  1166.         {
  1167.             for (size=0;size<4;size++) if (global->Test_Size[size])
  1168.             {
  1169.                 if (working) working=SpeedTest(global,global->Test_Size[size],offset&3,memtype);
  1170.             }
  1171.         }
  1172.  
  1173.         if (memtype & MEMF_CHIP) memtype=0;
  1174.         else memtype=MEMF_CHIP;
  1175.     }
  1176.  
  1177. #ifndef    SCSI_SPEED
  1178.  
  1179.     CleanUpFiles(global);
  1180.  
  1181. #endif    /* !SCSI_SPEED */
  1182.  
  1183.     if ((working) && (global->CPU_Count))
  1184.     {
  1185.         AddDisplayLine(global,"");
  1186.         global->CPU_Total=(((global->CPU_Total << 1) / global->CPU_Count)+1) >> 1;
  1187.         global->CPU_Count=(((global->Base_CPU * global->CPU_Total) / 50000)+1) >> 1;
  1188.         sprintf(p,"Average CPU Available: %ld%%  |  CPU Availability index: %ld",global->CPU_Total,global->CPU_Count);
  1189.         AddDisplayLine(global,p);
  1190.     }
  1191. }
  1192.  
  1193. #ifdef    SCSI_SPEED
  1194.  
  1195. void StartTest(struct DiskSpeed *global)
  1196. {
  1197. APTR    oldwindow;
  1198. char    *p;
  1199. char    *unit=NULL;
  1200. ULONG    scsi_unit;
  1201.  
  1202.     oldwindow=global->Me->pr_WindowPtr;
  1203.     global->Me->pr_WindowPtr=(APTR)(-1L);
  1204.  
  1205.     FreeDisplayList(global);
  1206.  
  1207.     AddDisplayLine(global,COPYRIGHT);
  1208.     AddDisplayLine(global,"------------------------------------------------------------");
  1209.  
  1210.     p=global->Device;
  1211.     while (*p)
  1212.     {
  1213.         if (*p==':') unit=p;
  1214.         p++;
  1215.     }
  1216.  
  1217.     p=unit;
  1218.  
  1219.     if (unit)
  1220.     {
  1221.         *unit='\0';
  1222.         unit++;
  1223.         scsi_unit=0;
  1224.         while ((unit) && (*unit))
  1225.         {
  1226.             if ((*unit < '0') || (*unit >'9')) unit=NULL;
  1227.             else
  1228.             {
  1229.                 scsi_unit*=10;
  1230.                 scsi_unit+=*unit-'0';
  1231.                 unit++;
  1232.             }
  1233.         }
  1234.     }
  1235.  
  1236.     if (unit)
  1237.     {
  1238.         memset(&(global->DiskIO),0,sizeof(struct IOExtTD));
  1239.         if (global->DiskIO.iotd_Req.io_Message.mn_ReplyPort=CreatePort(NULL,0))
  1240.         {
  1241.             if (!OpenDevice(global->Device,scsi_unit,&(global->DiskIO),NULL))
  1242.             {
  1243.                 unit=NULL;
  1244.                 *p=':';
  1245.                 DoTests(global);
  1246.                 CloseDevice(&(global->DiskIO));
  1247.             }
  1248.             DeletePort(global->DiskIO.iotd_Req.io_Message.mn_ReplyPort);
  1249.         }
  1250.         if (unit) AddDisplayLine(global,"Error:  Could not open device specified");
  1251.     }
  1252.     else AddDisplayLine(global,"Error:  Bad device specification.");
  1253.  
  1254.     if (p) *p=':';
  1255.  
  1256.     global->Me->pr_WindowPtr=oldwindow;
  1257. }
  1258.  
  1259. #else    /* SCSI_SPEED */
  1260.  
  1261. void StartTest(struct DiskSpeed *global)
  1262. {
  1263. BPTR    lock;
  1264. BPTR    newlock;
  1265. APTR    oldwindow;
  1266.  
  1267.     oldwindow=global->Me->pr_WindowPtr;
  1268.     global->Me->pr_WindowPtr=(APTR)(-1L);
  1269.  
  1270.     FreeDisplayList(global);
  1271.  
  1272.     AddDisplayLine(global,COPYRIGHT);
  1273.     AddDisplayLine(global,"------------------------------------------------------------");
  1274.  
  1275.     if (lock=Lock(global->Device,ACCESS_READ))
  1276.     {
  1277.         lock=CurrentDir(lock);
  1278.         if (newlock=CreateDir(TEST_DIR))
  1279.         {
  1280.             UnLock(newlock);
  1281.             if (newlock=Lock(TEST_DIR,ACCESS_READ))
  1282.             {
  1283.                 newlock=CurrentDir(newlock);
  1284.  
  1285.                 /*
  1286.                  * Now do all of the tests...
  1287.                  */
  1288.                 DoTests(global);
  1289.  
  1290.                 newlock=CurrentDir(newlock);
  1291.                 UnLock(newlock);
  1292.             }
  1293.             else AddDisplayLine(global,"Error:  Could not access test directory.");
  1294.             DeleteFile(TEST_DIR);
  1295.         }
  1296.         else AddDisplayLine(global,"Error:  Could not create test directory.");
  1297.         lock=CurrentDir(lock);
  1298.         UnLock(lock);
  1299.     }
  1300.     else AddDisplayLine(global,"Error:  Could not get a lock on test device.");
  1301.  
  1302.     global->Me->pr_WindowPtr=oldwindow;
  1303. }
  1304.  
  1305. #endif    /* SCSI_SPEED */
  1306.  
  1307. VOID SetVersionStrings(struct DiskSpeed *global)
  1308. {
  1309. UWORD    flags=((struct ExecBase *)(SysBase))->AttnFlags;
  1310. char    *p;
  1311.  
  1312.     strcpy(global->CPU_Type,"68000");
  1313.     p=&(global->CPU_Type[3]);
  1314.     if (flags & AFF_68010) *p='1';
  1315.     if (flags & AFF_68020) *p='2';
  1316.     if (flags & AFF_68030) *p='3';
  1317.     if (flags & AFF_68040) *p='4';
  1318.  
  1319.     sprintf(global->Exec_Ver,"%ld.%ld",(ULONG)(SysBase->lib_Version),(ULONG)(((struct ExecBase *)SysBase)->SoftVer));
  1320. }
  1321.  
  1322. /*
  1323.  * A simple string check that also works with '=' at the end of the string
  1324.  */
  1325. char *Check_String(char *arg,char *match)
  1326. {
  1327. char    *p;
  1328. char    *next=NULL;
  1329.  
  1330.     p=arg;
  1331.     while (*p)
  1332.     {
  1333.         if (*p=='=')
  1334.         {
  1335.             *p='\0';
  1336.             next=p;
  1337.         }
  1338.         else p++;
  1339.     }
  1340.  
  1341.     if (stricmp(arg,match))
  1342.     {
  1343.         if (next) *next='=';
  1344.         next=NULL;
  1345.     }
  1346.     else
  1347.     {
  1348.         if (next) next++;
  1349.         else next=p;
  1350.     }
  1351.  
  1352.     return(next);
  1353. }
  1354.  
  1355. /*
  1356.  * This routine closes down the GUI
  1357.  */
  1358. void Close_GUI(struct DiskSpeed *global)
  1359. {
  1360.     if (global->Window)
  1361.     {
  1362.         CloseWindow(global->Window);
  1363.         global->Window=NULL;
  1364.     }
  1365.     if (global->List)
  1366.     {
  1367.         FreeListGadget(global->List);
  1368.         global->List=NULL;
  1369.     }
  1370.     if (global->ri)
  1371.     {
  1372.         CleanUp_RenderInfo(global->ri);
  1373.         global->ri=NULL;
  1374.     }
  1375. }
  1376.  
  1377. /*
  1378.  * This routine is used to open the GUI...
  1379.  */
  1380. BOOL Open_GUI(struct DiskSpeed *global)
  1381. {
  1382.     BOOL        worked=FALSE;
  1383.     UWORD        internalwidth;
  1384.     UWORD        internalheight;
  1385. struct    Gadget        *gad=NULL;
  1386. struct    RenderInfo    *ri_temp;
  1387. struct    NewWindow    nw;
  1388.  
  1389.     if (!global->Window)
  1390.     {
  1391.         /* Now, open/set up the GUI... */
  1392.         nw.LeftEdge=0;
  1393.         nw.TopEdge=0;
  1394.         nw.Width=540;
  1395.         nw.Height=169;
  1396.         nw.DetailPen=-1;
  1397.         nw.BlockPen=-1;
  1398.         nw.IDCMPFlags=GADGETDOWN|GADGETUP|CLOSEWINDOW|ACTIVEWINDOW|MOUSEBUTTONS;
  1399.         nw.Flags=SMART_REFRESH|ACTIVATE|NOCAREREFRESH|RMBTRAP|WINDOWCLOSE|WINDOWDEPTH|WINDOWDRAG;
  1400.         nw.FirstGadget=NULL;
  1401.         nw.CheckMark=NULL;
  1402.         nw.Title=COPYRIGHT;
  1403.         nw.Type=WBENCHSCREEN;
  1404.  
  1405.         /*
  1406.          * Take a quick guess at window title bar size
  1407.          */
  1408.         if (ri_temp=Get_RenderInfo(NULL))
  1409.         {
  1410.             nw.Height+=ri_temp->WindowTitle;
  1411.             CleanUp_RenderInfo(ri_temp);
  1412.         }
  1413.  
  1414.         if (global->Window=OpenWindow(&nw)) if ((global->Window->Height-global->Window->BorderTop-global->Window->BorderBottom) > 120)
  1415.         {
  1416.             SetWindowTitles(global->Window,COPYRIGHT,COPYRIGHT);
  1417.             if (global->ri=Get_RenderInfo(global->Window->WScreen))
  1418.             {
  1419.                 internalwidth=global->Window->Width-global->Window->BorderLeft-global->Window->BorderRight;
  1420.                 internalheight=global->Window->Height-global->Window->BorderTop-global->Window->BorderBottom;
  1421.  
  1422.                 global->List=InitListGadget(&TOPAZ80,&gad,1,
  1423.                                 global->ri->Highlight,
  1424.                                 global->ri->Shadow,
  1425.                                 global->Window->BorderLeft+4,
  1426.                                 global->Window->BorderTop+33,
  1427.                                 internalwidth-8,
  1428.                                 internalheight-49);
  1429.  
  1430.                 /*
  1431.                  * Set up borders for the string gadgets
  1432.                  */
  1433.                 global->StringBorder[0].LeftEdge=-5;
  1434.                 global->StringBorder[0].TopEdge=-3;
  1435.                 global->StringBorder[0].FrontPen=global->ri->Highlight;
  1436.                 global->StringBorder[0].DrawMode=JAM1;
  1437.                 global->StringBorder[0].Count=5;
  1438.                 global->StringBorder[0].XY=&(global->StringVectors[0*5*2]);
  1439.                 global->StringBorder[0].NextBorder=&(global->StringBorder[1]);
  1440.  
  1441.                 global->StringBorder[1]=global->StringBorder[0];
  1442.                 global->StringBorder[1].FrontPen=global->ri->Shadow;
  1443.                 global->StringBorder[1].XY=&(global->StringVectors[1*5*2]);
  1444.                 global->StringBorder[1].NextBorder=&(global->StringBorder[2]);
  1445.  
  1446.                 global->StringBorder[2].LeftEdge=-3;
  1447.                 global->StringBorder[2].TopEdge=-2;
  1448.                 global->StringBorder[2].FrontPen=global->ri->Shadow;
  1449.                 global->StringBorder[2].DrawMode=JAM1;
  1450.                 global->StringBorder[2].Count=5;
  1451.                 global->StringBorder[2].XY=&(global->StringVectors[2*5*2]);
  1452.                 global->StringBorder[2].NextBorder=&(global->StringBorder[3]);
  1453.  
  1454.                 global->StringBorder[3]=global->StringBorder[2];
  1455.                 global->StringBorder[3].FrontPen=global->ri->Highlight;
  1456.                 global->StringBorder[3].XY=&(global->StringVectors[3*5*2]);
  1457.                 global->StringBorder[3].NextBorder=NULL;
  1458.  
  1459.                 FillTopLeft_Border(&(global->StringBorder[0]),internalwidth-81,14);
  1460.                 FillBottomRight_Border(&(global->StringBorder[1]),internalwidth-81,14);
  1461.                 FillTopLeft_Border(&(global->StringBorder[2]),internalwidth-85,12);
  1462.                 FillBottomRight_Border(&(global->StringBorder[3]),internalwidth-85,12);
  1463.  
  1464.                 /*
  1465.                  * Now add the few other gadgets to the window...
  1466.                  */
  1467.                 global->DeviceGadget.NextGadget=gad;        gad=&(global->DeviceGadget);
  1468.                 gad->LeftEdge=82+global->Window->BorderLeft;
  1469.                 gad->TopEdge=5+global->Window->BorderTop;
  1470.                 gad->Width=internalwidth-91;
  1471.                 gad->Height=8;
  1472.                 gad->Flags=GADGHCOMP;
  1473.                 gad->Activation=RELVERIFY;
  1474.                 gad->GadgetType=STRGADGET;
  1475.                 gad->GadgetRender=(APTR)&(global->StringBorder[0]);
  1476.                 gad->GadgetText=&(global->DeviceText);
  1477.                 gad->SpecialInfo=(APTR)&(global->DeviceInfo);
  1478.                 gad->GadgetID=DEVICE_GADGET;
  1479.  
  1480.                 global->CommentsGadget=global->DeviceGadget;
  1481.                 global->CommentsGadget.NextGadget=gad;        gad=&(global->CommentsGadget);
  1482.                 gad->TopEdge+=15;
  1483.                 gad->GadgetText=&(global->CommentsText);
  1484.                 gad->SpecialInfo=(APTR)&(global->CommentsInfo);
  1485.                 gad->GadgetID=COMMENT_GADGET;
  1486.  
  1487.                 global->DeviceInfo.Buffer=global->Device;
  1488.                 global->DeviceInfo.UndoBuffer=global->Undo;
  1489.                 global->DeviceInfo.MaxChars=250;
  1490.                 global->CommentsInfo=global->DeviceInfo;
  1491.                 global->CommentsInfo.Buffer=global->Comments;
  1492.  
  1493.                 global->DeviceText.FrontPen=1;
  1494.                 global->DeviceText.BackPen=0;
  1495.                 global->DeviceText.DrawMode=JAM2;
  1496.                 global->DeviceText.LeftEdge=-64;    /* 8 x 8 */
  1497.                 global->DeviceText.TopEdge=0;
  1498.                 global->DeviceText.ITextFont=&TOPAZ80;
  1499.                 global->DeviceText.IText="Device:";
  1500.  
  1501.                 global->CommentsText=global->DeviceText;
  1502.                 global->CommentsText.LeftEdge=-80;    /* 10 x 8 */
  1503.                 global->CommentsText.IText="Comments:";
  1504.  
  1505.                 /*
  1506.                  * Set up borders for the action gadgets (One set for all gadgets...)
  1507.                  */
  1508.                 global->ActionBorder[0].FrontPen=global->ri->Highlight;
  1509.                 global->ActionBorder[0].DrawMode=JAM1;
  1510.                 global->ActionBorder[0].Count=5;
  1511.                 global->ActionBorder[0].XY=&(global->ActionVectors[0*5*2]);
  1512.                 global->ActionBorder[0].NextBorder=&(global->ActionBorder[1]);
  1513.  
  1514.                 global->ActionBorder[1].FrontPen=global->ri->Shadow;
  1515.                 global->ActionBorder[1].DrawMode=JAM1;
  1516.                 global->ActionBorder[1].Count=5;
  1517.                 global->ActionBorder[1].XY=&(global->ActionVectors[1*5*2]);
  1518.                 global->ActionBorder[1].NextBorder=NULL;
  1519.  
  1520.                 global->ActionBorder[2]=global->ActionBorder[0];
  1521.                 global->ActionBorder[2].FrontPen=global->ri->Shadow;
  1522.                 global->ActionBorder[2].NextBorder=&(global->ActionBorder[3]);
  1523.  
  1524.                 global->ActionBorder[3]=global->ActionBorder[1];
  1525.                 global->ActionBorder[3].FrontPen=global->ri->Highlight;
  1526.  
  1527.                 FillTopLeft_Border(&(global->ActionBorder[0]),108,12);
  1528.                 FillBottomRight_Border(&(global->ActionBorder[1]),108,12);
  1529.  
  1530.                 /*
  1531.                  * Now for the two action gadgets at the bottom...
  1532.                  */
  1533.                 global->StartTestGadget.NextGadget=gad;        gad=&(global->StartTestGadget);
  1534.                 gad->LeftEdge=global->Window->BorderLeft+4;
  1535.                 gad->TopEdge=global->Window->Height-global->Window->BorderBottom-14;
  1536.                 gad->Width=108;
  1537.                 gad->Height=12;
  1538.                 gad->Flags=((global->ri->Shadow==global->ri->Highlight) ? GADGHCOMP : GADGHIMAGE);
  1539.                 gad->Activation=RELVERIFY;
  1540.                 gad->GadgetType=BOOLGADGET;
  1541.                 gad->GadgetRender=(APTR)&(global->ActionBorder[0]);
  1542.                 gad->SelectRender=(APTR)&(global->ActionBorder[2]);
  1543.                 gad->GadgetText=&(global->StartTest);
  1544.                 gad->GadgetID=TEST_GADGET;
  1545.  
  1546.                 global->StartTest.FrontPen=1;
  1547.                 global->StartTest.DrawMode=JAM1;
  1548.                 global->StartTest.ITextFont=&TOPAZ80;
  1549.                 global->StartTest.IText=START_TEST;
  1550.                 global->StartTest.TopEdge=2;
  1551.                 global->StartTest.LeftEdge=14;
  1552.  
  1553.                 global->SaveResultsGadget=global->StartTestGadget;
  1554.                 global->SaveResultsGadget.NextGadget=gad;    gad=&(global->SaveResultsGadget);
  1555.                 gad->LeftEdge=global->Window->Width-global->Window->BorderRight-112;
  1556.                 gad->GadgetText=&(global->SaveResults);
  1557.                 gad->GadgetID=SAVE_GADGET;
  1558.  
  1559.                 global->SaveResults=global->StartTest;
  1560.                 global->SaveResults.IText=SAVE_RESULTS;
  1561.                 global->SaveResults.LeftEdge=6;
  1562.  
  1563.                 global->StopTestGadget=global->StartTestGadget;
  1564.                 global->StopTestGadget.NextGadget=gad;    gad=&(global->StopTestGadget);
  1565.                 gad->LeftEdge=(global->Window->Width-108)/2;
  1566.                 gad->GadgetText=&(global->StopTest);
  1567.                 gad->GadgetID=STOP_GADGET;
  1568.  
  1569.                 global->StopTest=global->StartTest;
  1570.                 global->StopTest.IText=STOP_TEST;
  1571.                 global->StopTest.LeftEdge=18;
  1572.  
  1573.                 if (global->List)
  1574.                 {
  1575.                     AddGList(global->Window,gad,-1,-1,NULL);
  1576.                     RefreshGList(gad,global->Window,NULL,-1);
  1577.                     worked=TRUE;
  1578.                 }
  1579.             }
  1580.         }
  1581.  
  1582.         if (!worked) Close_GUI(global);
  1583.     }
  1584.  
  1585.     return(global->Window!=NULL);
  1586. }
  1587.  
  1588. /*
  1589.  * This routine will append to the end of a file the results currently in memory...
  1590.  */
  1591. void Save_Results(struct DiskSpeed *global)
  1592. {
  1593.     BPTR        fh;
  1594. struct    Node        *node;
  1595.  
  1596.     if (fh=Open(RESULTS_FILE,MODE_OLDFILE))
  1597.     {
  1598.         Seek(fh,0,OFFSET_END);
  1599.         Write(fh,"\n\n\n",2);
  1600.     }
  1601.     else fh=Open(RESULTS_FILE,MODE_NEWFILE);
  1602.  
  1603.     if (fh)
  1604.     {
  1605.         node=(struct Node *)(global->TextList.mlh_Head);
  1606.         while (node->ln_Succ)
  1607.         {
  1608.             Write(fh,node->ln_Name,strlen(node->ln_Name));
  1609.             Write(fh,"\n",1);
  1610.             node=node->ln_Succ;
  1611.         }
  1612.  
  1613.         Close(fh);
  1614.     }
  1615. }
  1616.  
  1617. /***********************************************************/
  1618. /**                                                       **/
  1619. /**  This is the config requester code for DiskSpeed 4.2  **/
  1620. /**                                                       **/
  1621. /***********************************************************/
  1622.  
  1623. /*
  1624.  * Ok, now for some silly vectors that will be needed to make the 1.3 versions
  1625.  * of some gadgets that are very simple under 2.0
  1626.  */
  1627. SHORT    CheckVec[18]={9,5, 12,8, 18,2, 19,2, 17,2, 11,8, 8,5, 7,5, 10,8};
  1628. SHORT    CheckBox1[10]={24,0, 1,0, 1,9, 0,10, 0,0};
  1629. SHORT    CheckBox2[10]={1,10, 24,10, 24,1, 25,0, 25,10};
  1630.  
  1631. struct    Border    Check_Box2={0,0,0,0,JAM2,5,CheckBox2,NULL};
  1632. struct    Border    Check_Box1={0,0,0,0,JAM2,5,CheckBox1,&Check_Box2};
  1633. struct    Border    CheckOn={0,0,1,0,JAM2,9,CheckVec,&Check_Box1};
  1634. struct    Border    CheckOff={0,0,0,0,JAM2,9,CheckVec,&Check_Box1};
  1635.  
  1636. UBYTE    *BufNames[]={    "Test Buffer 1",
  1637.             "Test Buffer 2",
  1638.             "Test Buffer 3",
  1639.             "Test Buffer 4"    };
  1640.  
  1641. UBYTE    *CheckGads[]={    "DIR",
  1642.             "SEEK",
  1643.             "NOCPU",
  1644.             "LONG",
  1645.             "WORD",
  1646.             "BYTE",
  1647.             "FAST",
  1648.             "CHIP"    };
  1649.  
  1650. SHORT    CheckPos[]={    8,4,
  1651.             8,15,
  1652.             8,26,
  1653.             8,123,
  1654.             8,134,
  1655.             8,145,
  1656.             87,123,
  1657.             87,134    };
  1658.  
  1659. struct    ConfigRequest
  1660. {
  1661. struct    Requester    req;        /* The requester */
  1662.  
  1663. struct    Border        reqBorders[4];    /* Border structures for the requester */
  1664. struct    Border        StringBorder[4];
  1665. struct    Border        BoolBorder[4];
  1666.  
  1667. struct    Gadget        CheckGads[8];    /* The 8 check gadgets */
  1668. struct    Gadget        OkGadget;
  1669. struct    Gadget        MinTimeGadget;
  1670. struct    Gadget        BufGads[4];
  1671.  
  1672. struct    StringInfo    MinTimeString;
  1673. struct    StringInfo    BufString[4];
  1674.  
  1675. struct    IntuiText    reqText[2];    /* Text structures for the requester */
  1676. struct    IntuiText    CheckText[8];    /* Text for the 8 check gadgets */
  1677. struct    IntuiText    OkText;
  1678. struct    IntuiText    MinTimeText;
  1679. struct    IntuiText    BufText[4];
  1680.  
  1681.     SHORT        reqVecs[5*2*4];    /* The vectors for the req border */
  1682.     SHORT        StringVectors[5*2*4];
  1683.     SHORT        BoolVecs[5*2*2];
  1684.  
  1685.     UBYTE        MinTimeBuf[12];
  1686.     UBYTE        Buf[12*4];
  1687.     UBYTE        Undo[12];
  1688. };
  1689.  
  1690. #define    REQ_HEIGHT    165
  1691. #define    REQ_WIDTH    225
  1692.  
  1693. #define    OK_GADGET    99
  1694.  
  1695. /*
  1696.  * This routine will display and handle the config window
  1697.  */
  1698. void Do_Config(struct DiskSpeed *global)
  1699. {
  1700. struct    ConfigRequest    *config;
  1701. struct    Gadget        *gad=NULL;
  1702. struct    IntuiMessage    *msg;
  1703.     short        loop;
  1704.     BOOL        error=TRUE;
  1705.     short        temp;
  1706.  
  1707.     Check_Box1.FrontPen=global->ri->Highlight;
  1708.     Check_Box2.FrontPen=global->ri->Shadow;
  1709.  
  1710.     if (config=AllocMem(sizeof(struct ConfigRequest),MEMF_PUBLIC|MEMF_CLEAR))
  1711.     {
  1712.         InitRequester(&(config->req));
  1713.  
  1714.         config->req.LeftEdge=global->Window->BorderLeft+2;
  1715.         config->req.TopEdge=global->Window->BorderTop+1;
  1716.         config->req.Width=global->Window->Width-global->Window->BorderLeft-global->Window->BorderRight-4;
  1717.         config->req.Height=global->Window->Height-global->Window->BorderTop-global->Window->BorderBottom-2;
  1718.         config->req.ReqBorder=config->reqBorders;
  1719.         config->req.ReqText=config->reqText;
  1720.  
  1721.         /*
  1722.          * Do the OK gadget
  1723.          */
  1724.         config->OkGadget.NextGadget=gad;
  1725.         gad=&(config->OkGadget);
  1726.  
  1727.         gad->LeftEdge=135;
  1728.         gad->TopEdge=148;
  1729.         gad->Width=82;
  1730.         gad->Height=13;
  1731.         gad->Flags=GFLG_GADGHIMAGE;
  1732.         gad->Activation=GACT_RELVERIFY;
  1733.         gad->GadgetType=GTYP_REQGADGET|GTYP_BOOLGADGET;
  1734.         gad->GadgetRender=(APTR)(&(config->BoolBorder[0]));
  1735.         gad->SelectRender=(APTR)(&(config->BoolBorder[2]));
  1736.         gad->GadgetText=&(config->OkText);
  1737.         gad->GadgetID=OK_GADGET;
  1738.  
  1739.         config->OkText.FrontPen=1;
  1740.         config->OkText.DrawMode=JAM2;
  1741.         config->OkText.LeftEdge=33;
  1742.         config->OkText.TopEdge=3;
  1743.         config->OkText.ITextFont=&TOPAZ80;
  1744.         config->OkText.IText="OK";
  1745.  
  1746.         /*
  1747.          * Set up the requester text structures
  1748.          */
  1749.         config->reqText[0]=config->OkText;
  1750.         config->reqText[0].LeftEdge=9;
  1751.         config->reqText[0].TopEdge=42;
  1752.         config->reqText[0].IText="Read/Write Buffer Sizes";
  1753.         config->reqText[0].NextText=&(config->reqText[1]);
  1754.  
  1755.         config->reqText[1]=config->reqText[0];
  1756.         config->reqText[1].TopEdge=111;
  1757.         config->reqText[1].IText="Read/Write Buffer Types";
  1758.         config->reqText[1].NextText=NULL;
  1759.  
  1760.         /*
  1761.          * Now, build the border structures for the requester
  1762.          */
  1763.         config->reqBorders[0].FrontPen=global->ri->Shadow;
  1764.         config->reqBorders[0].DrawMode=JAM2;
  1765.         config->reqBorders[0].Count=5;
  1766.         config->reqBorders[0].XY=&(config->reqVecs[5*2*0]);
  1767.         config->reqBorders[0].NextBorder=&(config->reqBorders[1]);
  1768.  
  1769.         config->reqBorders[1]=config->reqBorders[0];
  1770.         config->reqBorders[1].FrontPen=global->ri->Highlight;
  1771.         config->reqBorders[1].XY=&(config->reqVecs[5*2*1]);
  1772.         config->reqBorders[1].NextBorder=&(config->reqBorders[2]);
  1773.  
  1774.         config->reqBorders[2]=config->reqBorders[1];
  1775.         config->reqBorders[2].TopEdge=1;
  1776.         config->reqBorders[2].LeftEdge=2;
  1777.         config->reqBorders[2].XY=&(config->reqVecs[5*2*2]);
  1778.         config->reqBorders[2].NextBorder=&(config->reqBorders[3]);
  1779.  
  1780.         config->reqBorders[3]=config->reqBorders[0];
  1781.         config->reqBorders[3].TopEdge=1;
  1782.         config->reqBorders[3].LeftEdge=2;
  1783.         config->reqBorders[3].XY=&(config->reqVecs[5*2*3]);
  1784.         config->reqBorders[3].NextBorder=NULL;
  1785.  
  1786.         FillTopLeft_Border(&(config->reqBorders[0]),REQ_WIDTH,REQ_HEIGHT);
  1787.         FillBottomRight_Border(&(config->reqBorders[1]),REQ_WIDTH,REQ_HEIGHT);
  1788.         FillTopLeft_Border(&(config->reqBorders[2]),REQ_WIDTH-4,REQ_HEIGHT-2);
  1789.         FillBottomRight_Border(&(config->reqBorders[3]),REQ_WIDTH-4,REQ_HEIGHT-2);
  1790.  
  1791.         /*
  1792.          * Now, set up the string gadget border structure (it is the same for all)
  1793.          */
  1794.         config->StringBorder[0]=config->reqBorders[1];
  1795.         config->StringBorder[0].LeftEdge=-5;
  1796.         config->StringBorder[0].TopEdge=-3;
  1797.         config->StringBorder[0].XY=&(config->StringVectors[0*5*2]);
  1798.         config->StringBorder[0].NextBorder=&(config->StringBorder[1]);
  1799.  
  1800.         config->StringBorder[1]=config->StringBorder[0];
  1801.         config->StringBorder[1].FrontPen=global->ri->Shadow;
  1802.         config->StringBorder[1].XY=&(config->StringVectors[1*5*2]);
  1803.         config->StringBorder[1].NextBorder=&(config->StringBorder[2]);
  1804.  
  1805.         config->StringBorder[2]=config->StringBorder[1];
  1806.         config->StringBorder[2].LeftEdge=-3;
  1807.         config->StringBorder[2].TopEdge=-2;
  1808.         config->StringBorder[2].XY=&(config->StringVectors[2*5*2]);
  1809.         config->StringBorder[2].NextBorder=&(config->StringBorder[3]);
  1810.  
  1811.         config->StringBorder[3]=config->StringBorder[2];
  1812.         config->StringBorder[3].FrontPen=global->ri->Highlight;
  1813.         config->StringBorder[3].XY=&(config->StringVectors[3*5*2]);
  1814.         config->StringBorder[3].NextBorder=NULL;
  1815.  
  1816.         FillTopLeft_Border(&(config->StringBorder[0]),86,13);
  1817.         FillBottomRight_Border(&(config->StringBorder[1]),86,13);
  1818.         FillTopLeft_Border(&(config->StringBorder[2]),82,11);
  1819.         FillBottomRight_Border(&(config->StringBorder[3]),82,11);
  1820.  
  1821.         /*
  1822.          * Now set up the rel-verify gadget border structure
  1823.          * (Also the same everywhere)
  1824.          */
  1825.         config->BoolBorder[0]=config->StringBorder[0];
  1826.         config->BoolBorder[0].LeftEdge=0;
  1827.         config->BoolBorder[0].TopEdge=0;
  1828.         config->BoolBorder[0].XY=&(config->BoolVecs[0*5*2]);
  1829.         config->BoolBorder[0].NextBorder=&(config->BoolBorder[1]);
  1830.  
  1831.         config->BoolBorder[1]=config->BoolBorder[0];
  1832.         config->BoolBorder[1].FrontPen=global->ri->Shadow;
  1833.         config->BoolBorder[1].XY=&(config->BoolVecs[1*5*2]);
  1834.         config->BoolBorder[1].NextBorder=NULL;
  1835.  
  1836.         config->BoolBorder[2]=config->BoolBorder[0];
  1837.         config->BoolBorder[2].FrontPen=global->ri->Shadow;
  1838.         config->BoolBorder[2].NextBorder=&(config->BoolBorder[3]);
  1839.  
  1840.         config->BoolBorder[3]=config->BoolBorder[1];
  1841.         config->BoolBorder[3].FrontPen=global->ri->Highlight;
  1842.  
  1843.         FillTopLeft_Border(&(config->BoolBorder[0]),82,13);
  1844.         FillBottomRight_Border(&(config->BoolBorder[1]),82,13);
  1845.  
  1846.         /*
  1847.          * Do the MinTime gadget
  1848.          */
  1849.         config->MinTimeGadget.NextGadget=gad;
  1850.         gad=&(config->MinTimeGadget);
  1851.  
  1852.         gad->LeftEdge=128;
  1853.         gad->TopEdge=20;
  1854.         gad->Width=76;
  1855.         gad->Height=8;
  1856.         gad->Flags=GFLG_GADGHCOMP;
  1857.         gad->Activation=GACT_RELVERIFY|GACT_LONGINT;
  1858.         gad->GadgetType=GTYP_STRGADGET;
  1859.         gad->GadgetRender=(APTR)(&(config->StringBorder[0]));
  1860.         gad->GadgetText=&(config->MinTimeText);
  1861.         gad->SpecialInfo=(APTR)(&(config->MinTimeString));
  1862.  
  1863.         config->MinTimeString.Buffer=config->MinTimeBuf;
  1864.         config->MinTimeString.UndoBuffer=config->Undo;
  1865.         config->MinTimeString.MaxChars=11;
  1866.         config->MinTimeString.LongInt=global->Min_Time;
  1867.         sprintf(config->MinTimeBuf,"%ld",config->MinTimeString.LongInt);
  1868.  
  1869.         config->MinTimeText=config->OkText;
  1870.         config->MinTimeText.TopEdge=-12;
  1871.         config->MinTimeText.LeftEdge=12;
  1872.         config->MinTimeText.IText="MINTIME";
  1873.  
  1874.         /*
  1875.          * Now for the 4 buffer gadgets and the Default gadgets for them
  1876.          */
  1877.         for (loop=0;loop<4;loop++)
  1878.         {
  1879.             config->BufGads[loop]=config->MinTimeGadget;
  1880.             config->BufGads[loop].NextGadget=gad;
  1881.             gad=&(config->BufGads[loop]);
  1882.  
  1883.             gad->LeftEdge=136;
  1884.             gad->TopEdge=56+(loop*13);
  1885.             gad->GadgetText=&(config->BufText[loop]);
  1886.             gad->SpecialInfo=(APTR)(&(config->BufString[loop]));
  1887.  
  1888.             config->BufString[loop]=config->MinTimeString;
  1889.             config->BufString[loop].Buffer=&(config->Buf[loop*12]);
  1890.             config->BufString[loop].LongInt=global->Test_Size[loop];
  1891.             sprintf(config->BufString[loop].Buffer,"%ld",config->BufString[loop].LongInt);
  1892.  
  1893.             config->BufText[loop]=config->OkText;
  1894.             config->BufText[loop].TopEdge=0;
  1895.             config->BufText[loop].LeftEdge=-127;
  1896.             config->BufText[loop].IText=BufNames[loop];
  1897.         }
  1898.  
  1899.         /*
  1900.          * Now set up the checkmark gadgets...
  1901.          */
  1902.         for (loop=0;loop<8;loop++)
  1903.         {
  1904.             config->CheckGads[loop].NextGadget=gad;
  1905.             gad=&(config->CheckGads[loop]);
  1906.  
  1907.             gad->LeftEdge=CheckPos[(loop*2)];
  1908.             gad->TopEdge=CheckPos[(loop*2)+1];
  1909.             gad->Width=26;
  1910.             gad->Height=11;
  1911.             gad->Flags=GFLG_GADGHIMAGE;
  1912.             gad->Activation=GACT_TOGGLESELECT;
  1913.             gad->GadgetType=GTYP_REQGADGET|GTYP_BOOLGADGET;
  1914.             gad->GadgetRender=(APTR)(&CheckOff);
  1915.             gad->SelectRender=(APTR)(&CheckOn);
  1916.             gad->GadgetText=&(config->CheckText[loop]);
  1917.  
  1918.             /*
  1919.              * Now, set the initial selected state for this gadget
  1920.              */
  1921.             switch (loop)
  1922.             {
  1923. #ifdef    SCSI_SPEED
  1924.  
  1925.             case    0:
  1926.             case    1:    temp=FALSE; gad->Flags|=GFLG_DISABLED;    break;
  1927.             case    2:    temp=(CPU_Use_Base==FALSE);        break;
  1928.             case    3:    temp=TRUE; gad->Flags|=GFLG_DISABLED;    break;
  1929.             case    4:
  1930.             case    5:    temp=FALSE; gad->Flags|=GFLG_DISABLED;    break;
  1931.  
  1932. #else    /* SCSI_SPEED */
  1933.  
  1934.             case    0:    temp=(global->Test_DIR==TRUE);        break;
  1935.             case    1:    temp=(global->Test_SEEK==TRUE);        break;
  1936.             case    2:    temp=(CPU_Use_Base==FALSE);        break;
  1937.             case    3:    temp=(global->Align_Types & 4);        break;
  1938.             case    4:    temp=(global->Align_Types & 2);        break;
  1939.             case    5:    temp=(global->Align_Types & 1);        break;
  1940.  
  1941. #endif    /* SCSI_SPEED */
  1942.  
  1943.             case    6:    temp=(global->Mem_TYPES & MEMF_FAST);    break;
  1944.             case    7:    temp=(global->Mem_TYPES & MEMF_CHIP);    break;
  1945.             }
  1946.             if (temp) gad->Flags|=GFLG_SELECTED;
  1947.  
  1948.             config->CheckText[loop]=config->OkText;
  1949.             config->CheckText[loop].LeftEdge=30;
  1950.             config->CheckText[loop].TopEdge=2;
  1951.             config->CheckText[loop].IText=CheckGads[loop];
  1952.         }
  1953.  
  1954.         config->req.ReqGadget=gad;
  1955.  
  1956.         if (Request(&(config->req),global->Window))
  1957.         {
  1958.             error=FALSE;
  1959.             temp=TRUE;
  1960.             while(temp)
  1961.             {
  1962.                 WaitPort(global->Window->UserPort);
  1963.                 while (msg=(struct IntuiMessage *)GetMsg(global->Window->UserPort))
  1964.                 {
  1965.                     if (msg->Class==GADGETUP)
  1966.                     {
  1967.                         if (OK_GADGET==((struct Gadget *)(msg->IAddress))->GadgetID) temp=FALSE;
  1968.                     }
  1969.                     ReplyMsg((struct Message *)msg);
  1970.                 }
  1971.             }
  1972.  
  1973.             EndRequest(&(config->req),global->Window);
  1974.  
  1975.             /*
  1976.              * Ok, now get the information back out...
  1977.              */
  1978.             global->Min_Time=config->MinTimeString.LongInt;
  1979.  
  1980.             for (loop=0;loop<4;loop++)
  1981.             {
  1982.                 global->Test_Size[loop]=config->BufString[loop].LongInt;
  1983.             }
  1984.  
  1985.             for (loop=0;loop<8;loop++)
  1986.             {
  1987.                 temp=0;
  1988.                 if (config->CheckGads[loop].Flags & GFLG_SELECTED) temp=1;
  1989.                 switch (loop)
  1990.                 {
  1991.                 case    0:    global->Test_DIR=temp;        break;
  1992.                 case    1:    global->Test_SEEK=temp;        break;
  1993.                 case    2:    CPU_Use_Base=(!temp);        break;
  1994.                 case    3:    global->Align_Types &= (~4);
  1995.                         global->Align_Types |= temp<<2;    break;
  1996.                 case    4:    global->Align_Types &= (~2);
  1997.                         global->Align_Types |= temp<<1;    break;
  1998.                 case    5:    global->Align_Types &= (~1);
  1999.                         global->Align_Types |= temp;    break;
  2000.                 case    6:    global->Mem_TYPES &= (~MEMF_FAST);
  2001.                         global->Mem_TYPES |= (temp * MEMF_FAST);
  2002.                         break;
  2003.                 case    7:    global->Mem_TYPES &= (~MEMF_CHIP);
  2004.                         global->Mem_TYPES |= (temp * MEMF_CHIP);
  2005.                         break;
  2006.                 }
  2007.             }
  2008.         }
  2009.  
  2010.         FreeMem(config,sizeof(struct ConfigRequest));
  2011.     }
  2012.  
  2013.     if (error) AddDisplayLine(global,"Could not open configuration requester.");
  2014. }
  2015.  
  2016. /**********************************************************/
  2017. /**                                                      **/
  2018. /**  End of the config requester code for DiskSpeed 4.2  **/
  2019. /**                                                      **/
  2020. /**********************************************************/
  2021.  
  2022. /*
  2023.  * This routine is used to control the GUI
  2024.  */
  2025. void Do_GUI(struct DiskSpeed *global)
  2026. {
  2027.     BOOL        done=FALSE;
  2028. struct    IntuiMessage    *msg;
  2029.  
  2030.     while (!done)
  2031.     {
  2032.         WaitPort(global->Window->UserPort);
  2033.         while (msg=(struct IntuiMessage *)GetMsg(global->Window->UserPort))
  2034.         {
  2035.             if (!Check_ListGadget(global->Window,msg))
  2036.             {
  2037.                 if (msg->Class==CLOSEWINDOW) done=TRUE;
  2038.                 else if ((msg->Class==MOUSEBUTTONS) && (msg->Code==MENUDOWN)) Do_Config(global);
  2039.                 else if (msg->Class==GADGETUP)
  2040.                 {
  2041.                     switch(((struct Gadget *)(msg->IAddress))->GadgetID)
  2042.                     {
  2043.                     case DEVICE_GADGET:    ActivateGadget(&(global->CommentsGadget),global->Window,NULL);
  2044.                                 break;
  2045.                     case COMMENT_GADGET:    ActivateGadget(&(global->DeviceGadget),global->Window,NULL);
  2046.                                 break;
  2047.                     case TEST_GADGET:    SetWait(global->Window);
  2048.                                 StartTest(global);
  2049.                                 ClearWait(global->Window);
  2050.                                 break;
  2051.                     case SAVE_GADGET:    SetWait(global->Window);
  2052.                                 Save_Results(global);
  2053.                                 ClearWait(global->Window);
  2054.                                 break;
  2055.                     }
  2056.                 }
  2057.                 else if (msg->Class==ACTIVEWINDOW)
  2058.                 {
  2059.                     ActivateGadget(&(global->DeviceGadget),global->Window,NULL);
  2060.                 }
  2061.             }
  2062.             ReplyMsg((struct Message *)msg);
  2063.         }
  2064.     }
  2065.     /* Shut down GUI */
  2066.     Close_GUI(global);
  2067. }
  2068.  
  2069. /*
  2070.  * DRIVE/K    - select drive  (Default is current directory or scsi.device:6)
  2071.  * COMMENT/K    - set comment string
  2072.  * ALL/S    - select all tests
  2073.  * DIR/S    - setect DIR tests
  2074.  * SEEK/S    - select SEEK tests
  2075.  * CHIP/S    - select CHIP memory buffer tests
  2076.  * FAST/S    - select FAST memory buffer tests
  2077.  * LONG/S    - select LONG aligned tests
  2078.  * WORD/S    - select WORD aligned tests
  2079.  * BYTE/S    - select BYTE aligned tests
  2080.  * NOCPU/S    - turn off CPU availability tests
  2081.  * BUF1/K/N    - select buffer size 1
  2082.  * BUF2/K/N    - select buffer size 2
  2083.  * BUF3/K/N    - select buffer size 3
  2084.  * BUF4/K/N    - select buffer size 4
  2085.  * MINTIME/K/N    - select the minimum test time (default=8) in seconds
  2086.  * WINDOW/S    - use the GUI even though started from the CLI
  2087.  */
  2088.  
  2089. /*
  2090.  * do the command line parsing here...
  2091.  */
  2092. BOOL ParseArg(struct DiskSpeed *global,int argc,char *argv[],int start)
  2093. {
  2094. int    loop;
  2095. char    *arg;
  2096. char    *next;
  2097. BOOL    working=TRUE;
  2098. BOOL    window=FALSE;
  2099.  
  2100. #ifdef    SCSI_SPEED
  2101.     global->Align_Types=4;
  2102. #endif    /* SCSI_SPEED */
  2103.  
  2104.     for (loop=start;loop<argc;loop++)
  2105.     {
  2106.         arg=argv[loop];
  2107.         if (*arg=='?')
  2108.         {
  2109.             loop=argc;
  2110.             working=FALSE;
  2111.         }
  2112.         else if (next=Check_String(arg,"DRIVE"))
  2113.         {
  2114.             if (!(*next))
  2115.             {
  2116.                 loop++;
  2117.                 if (loop<argc) next=argv[loop];
  2118.             }
  2119.             if (strlen(next)>255) *next='\0';
  2120.             if (*next) strcpy(global->Device,next);
  2121.             else working=FALSE;
  2122.         }
  2123.         else if (next=Check_String(arg,"COMMENT"))
  2124.         {
  2125.             if (!(*next))
  2126.             {
  2127.                 loop++;
  2128.                 if (loop<argc) next=argv[loop];
  2129.             }
  2130.             if (strlen(next)>255) *next='\0';
  2131.             if (*next) strcpy(global->Comments,next);
  2132.             else working=FALSE;
  2133.         }
  2134.         else if (Check_String(arg,"ALL"))
  2135.         {
  2136.             /* All tests */
  2137.  
  2138. #ifndef    SCSI_SPEED
  2139.  
  2140.             global->Test_DIR=TRUE;
  2141.             global->Test_SEEK=TRUE;
  2142.             global->Align_Types=4|2|1;
  2143.  
  2144. #endif    /* !SCSI_SPEED */
  2145.  
  2146.             global->Mem_TYPES=MEMF_CHIP | MEMF_FAST;
  2147.         }
  2148.         else if (next=Check_String(arg,"BUF1"))
  2149.         {
  2150.             if (!(*next))
  2151.             {
  2152.                 loop++;
  2153.                 if (loop<argc) next=argv[loop];
  2154.             }
  2155.             if (*next) stcd_l(next,&(global->Test_Size[0]));
  2156.             else working=FALSE;
  2157.         }
  2158.         else if (next=Check_String(arg,"BUF2"))
  2159.         {
  2160.             if (!(*next))
  2161.             {
  2162.                 loop++;
  2163.                 if (loop<argc) next=argv[loop];
  2164.             }
  2165.             if (*next) stcd_l(next,&(global->Test_Size[1]));
  2166.             else working=FALSE;
  2167.         }
  2168.         else if (next=Check_String(arg,"BUF3"))
  2169.         {
  2170.             if (!(*next))
  2171.             {
  2172.                 loop++;
  2173.                 if (loop<argc) next=argv[loop];
  2174.             }
  2175.             if (*next) stcd_l(next,&(global->Test_Size[2]));
  2176.             else working=FALSE;
  2177.         }
  2178.         else if (next=Check_String(arg,"BUF4"))
  2179.         {
  2180.             if (!(*next))
  2181.             {
  2182.                 loop++;
  2183.                 if (loop<argc) next=argv[loop];
  2184.             }
  2185.             if (*next) stcd_l(next,&(global->Test_Size[3]));
  2186.             else working=FALSE;
  2187.         }
  2188.         else if (next=Check_String(arg,"MINTIME"))
  2189.         {
  2190.             if (!(*next))
  2191.             {
  2192.                 loop++;
  2193.                 if (loop<argc) next=argv[loop];
  2194.             }
  2195.             if (*next) stcd_l(next,&(global->Min_Time));
  2196.             else working=FALSE;
  2197.         }
  2198. #ifndef    SCSI_SPEED
  2199.  
  2200.         else if (Check_String(arg,"DIR")) global->Test_DIR=TRUE;
  2201.         else if (Check_String(arg,"SEEK")) global->Test_SEEK=TRUE;
  2202.         else if (Check_String(arg,"LONG")) global->Align_Types|=4;
  2203.         else if (Check_String(arg,"WORD")) global->Align_Types|=2;
  2204.         else if (Check_String(arg,"BYTE")) global->Align_Types|=1;
  2205.  
  2206. #endif    /* !SCSI_SPEED */
  2207.  
  2208.         else if (Check_String(arg,"CHIP")) global->Mem_TYPES|=MEMF_CHIP;
  2209.         else if (Check_String(arg,"FAST")) global->Mem_TYPES|=MEMF_FAST;
  2210.         else if (Check_String(arg,"NOCPU")) CPU_Use_Base=FALSE;
  2211.         else if (Check_String(arg,"WINDOW")) window=TRUE;
  2212.         else
  2213.         {    /* Did not match, so error */
  2214.             working=FALSE;
  2215.         }
  2216.     }
  2217.  
  2218.     if (global->Min_Time < 1) global->Min_Time=1;
  2219.  
  2220.     if (working) if (window) working=Open_GUI(global);
  2221.  
  2222.     return(working);
  2223. }
  2224.  
  2225. /*
  2226.  * This routine is called when we want to run from a GUI
  2227.  * Normally, it is only called when started from Workbench
  2228.  * or when the CLI WINDOW option is given...
  2229.  */
  2230. void DoWorkbench(struct DiskSpeed *global,int argc,char *argv[])
  2231. {
  2232. struct    WBStartup    *wbmsg;
  2233. struct    WBArg        *wbarg;
  2234.     BPTR        lock;
  2235. struct    DiskObject    *icon;
  2236.  
  2237.     wbmsg=(struct WBStartup *)argv;
  2238.  
  2239.     if ((wbarg=wbmsg->sm_ArgList) && (wbmsg->sm_NumArgs))
  2240.     {
  2241.         /*
  2242.          * Check if we were started as a project and
  2243.          * use that icon insted...
  2244.          */
  2245.         if ((wbmsg->sm_NumArgs) > 1) wbarg++;
  2246.  
  2247.         lock=CurrentDir(wbarg->wa_Lock);
  2248.  
  2249.         argc=0;
  2250.         if (icon=GetDiskObject(wbarg->wa_Name))
  2251.         {
  2252.             argv=icon->do_ToolTypes;
  2253.             while (argv[argc]) argc++;
  2254.             /*
  2255.              * Don't care about argument errors in tooltypes
  2256.              * since other things may have been in there...
  2257.              */
  2258.             ParseArg(global,argc,argv,0);
  2259.             FreeDiskObject(icon);
  2260.         }
  2261.  
  2262.         if (!argc)
  2263.         {
  2264.             /* All tests */
  2265.             global->Test_DIR=TRUE;
  2266.             global->Test_SEEK=TRUE;
  2267.             global->Align_Types=4|2|1;
  2268.             global->Mem_TYPES=MEMF_CHIP | MEMF_FAST;
  2269.         }
  2270.  
  2271.         if (Open_GUI(global)) Do_GUI(global);
  2272.  
  2273.         CurrentDir(lock);
  2274.     }
  2275. }
  2276.  
  2277. /*
  2278.  * This is the CLI starting point.  We do the command line parsing here...
  2279.  */
  2280. void DoCLI(struct DiskSpeed *global,int argc,char *argv[])
  2281. {
  2282.     if (ParseArg(global,argc,argv,1))
  2283.     {
  2284.         if (global->Window) Do_GUI(global);
  2285.         else StartTest(global);
  2286.     }
  2287.     else
  2288.     {
  2289. #ifdef    SCSI_SPEED
  2290.  
  2291.         AddDisplayLine(global,"DRIVE/K,ALL/S,CHIP/S,FAST/S,NOCPU/S,BUF1/K/N,BUF2/K/N,BUF3/K/N,BUF4/K/N,MINTIME/K/N,WINDOW/S");
  2292.  
  2293. #else    /* SCSI_SPEED */
  2294.  
  2295.         AddDisplayLine(global,"DRIVE/K,ALL/S,DIR/S,SEEK/S,CHIP/S,FAST/S,LONG/S,WORD/S,BYTE/S,NOCPU/S,BUF1/K/N,BUF2/K/N,BUF3/K/N,BUF4/K/N,MINTIME/K/N,WINDOW/S");
  2296.  
  2297. #endif    /* SCSI_SPEED */
  2298.     }
  2299. }
  2300.  
  2301. #ifdef    SCSI_SPEED
  2302.  
  2303. void main(int argc, char *argv[])
  2304. {
  2305. struct    DiskSpeed    *global;
  2306.  
  2307.     CPU_Use_Base=TRUE;    /* We want to test with CPU */
  2308.  
  2309.     if (IntuitionBase=OpenLibrary("intuition.library",33L))
  2310.     {
  2311.         if (GfxBase=OpenLibrary("graphics.library",33L))
  2312.         {
  2313.             if (LayersBase=OpenLibrary("layers.library",33L))
  2314.             {
  2315.                 if (IconBase=OpenLibrary("icon.library",33L))
  2316.                 {
  2317.                     if (global=AllocMem(sizeof(struct DiskSpeed),MEMF_PUBLIC|MEMF_CLEAR))
  2318.                     {
  2319.                         NewList((struct List *)&(global->TextList));
  2320.                         SetVersionStrings(global);
  2321.                         global->Me=(struct Process *)FindTask(NULL);
  2322.  
  2323.                         /* Standard MinTime */
  2324.                         global->Min_Time=MIN_TEST_TIME;
  2325.  
  2326.                         /* Standard sizes */
  2327.                         global->Test_Size[0]=0x200;
  2328.                         global->Test_Size[1]=0x1000;
  2329.                         global->Test_Size[2]=0x8000;
  2330.                         global->Test_Size[3]=0x40000;
  2331.  
  2332.                         if (global->timer=Init_Timer())
  2333.                         {
  2334.                             /*
  2335.                              * Now either set up Window or Output
  2336.                              * depending on where we were started...
  2337.                              *
  2338.                              * If we can not get Output, we set up the window...
  2339.                              */
  2340.                             if ((argc) && (global->Output=Output()))
  2341.                             {
  2342.                                 DoCLI(global,argc,argv);
  2343.                             }
  2344.                             else DoWorkbench(global,argc,argv);
  2345.  
  2346.                             Free_Timer(global->timer);
  2347.                         }
  2348.  
  2349.                         FreeDisplayList(global);
  2350.                         FreeMem(global,sizeof(struct DiskSpeed));
  2351.                     }
  2352.                     CloseLibrary(IconBase);
  2353.                 }
  2354.                 CloseLibrary(LayersBase);
  2355.             }
  2356.             CloseLibrary(GfxBase);
  2357.         }
  2358.         CloseLibrary(IntuitionBase);
  2359.     }
  2360. }
  2361.  
  2362. #else    /* SCSI_SPEED */
  2363.  
  2364. void main(int argc, char *argv[])
  2365. {
  2366. struct    DiskSpeed    *global;
  2367.  
  2368.     CPU_Use_Base=TRUE;    /* We want to test with CPU */
  2369.  
  2370.     if (IntuitionBase=OpenLibrary("intuition.library",33L))
  2371.     {
  2372.         if (GfxBase=OpenLibrary("graphics.library",33L))
  2373.         {
  2374.             if (LayersBase=OpenLibrary("layers.library",33L))
  2375.             {
  2376.                 if (IconBase=OpenLibrary("icon.library",33L))
  2377.                 {
  2378.                     if (global=AllocMem(sizeof(struct DiskSpeed),MEMF_PUBLIC|MEMF_CLEAR))
  2379.                     {
  2380.                         NewList((struct List *)&(global->TextList));
  2381.                         SetVersionStrings(global);
  2382.                         global->Me=(struct Process *)FindTask(NULL);
  2383.  
  2384.                         /* Standard MinTime */
  2385.                         global->Min_Time=MIN_TEST_TIME;
  2386.  
  2387.                         /* Standard sizes */
  2388.                         global->Test_Size[0]=0x200;
  2389.                         global->Test_Size[1]=0x1000;
  2390.                         global->Test_Size[2]=0x8000;
  2391.                         global->Test_Size[3]=0x40000;
  2392.  
  2393.                         if (global->fib=AllocMem(sizeof(struct FileInfoBlock),MEMF_PUBLIC))
  2394.                         {
  2395.                             if (global->timer=Init_Timer())
  2396.                             {
  2397.                                 /*
  2398.                                  * Now either set up Window or Output
  2399.                                  * depending on where we were started...
  2400.                                  *
  2401.                                  * If we can not get Output, we set up the window...
  2402.                                  */
  2403.                                 if ((argc) && (global->Output=Output()))
  2404.                                 {
  2405.                                     DoCLI(global,argc,argv);
  2406.                                 }
  2407.                                 else DoWorkbench(global,argc,argv);
  2408.  
  2409.                                 Free_Timer(global->timer);
  2410.                             }
  2411.                             FreeMem(global->fib,sizeof(struct FileInfoBlock));
  2412.                         }
  2413.  
  2414.                         FreeDisplayList(global);
  2415.                         FreeMem(global,sizeof(struct DiskSpeed));
  2416.                     }
  2417.                     CloseLibrary(IconBase);
  2418.                 }
  2419.                 CloseLibrary(LayersBase);
  2420.             }
  2421.             CloseLibrary(GfxBase);
  2422.         }
  2423.         CloseLibrary(IntuitionBase);
  2424.     }
  2425. }
  2426.  
  2427. #endif    /* SCSI_SPEED */
  2428.